{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import os,random,shutil\n",
    "np.random.seed(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1, 准备数据集\n",
    "#1，指定一些超参数：\n",
    "train_data_dir='E:\\PyProjects\\DataSet\\DogsVsCats_Tiny/train'\n",
    "val_data_dir='E:\\PyProjects\\DataSet\\DogsVsCats_Tiny/test' # keras中将测试集称为validation set\n",
    "train_samples_num=2000 # train set中全部照片数\n",
    "val_samples_num=800\n",
    "IMG_W,IMG_H,IMG_CH=150,150,3 # 单张图片的大小\n",
    "batch_size=16 # 不能是32，因为2000/32不能整除，后面会有影响。\n",
    "epochs=20  # 用比较少的epochs数目做演示，节约训练时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 此处的训练集和测试集并不是原始图片的train set和test set，而是用VGG16对图片提取的特征，这些特征组成新的train set和test set\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dropout, Flatten, Dense\n",
    "from keras import applications\n",
    "def save_bottlebeck_features():\n",
    "    datagen = ImageDataGenerator(rescale=1. / 255) # 不需图片增强\n",
    "\n",
    "    # build the VGG16 network\n",
    "    model = applications.VGG16(include_top=False, weights='imagenet') \n",
    "    # 使用imagenet的weights作为VGG16的初始weights,由于只是特征提取，故而只取前面的卷积层而不需要DenseLayer，故而include_top=False\n",
    "\n",
    "    generator = datagen.flow_from_directory( # 产生train set\n",
    "        train_data_dir,\n",
    "        target_size=(IMG_W, IMG_H),\n",
    "        batch_size=batch_size,\n",
    "        class_mode=None, \n",
    "        shuffle=False) # 必须为False，否则顺序打乱之后，和后面的label对应不上。\n",
    "    bottleneck_features_train = model.predict_generator(\n",
    "        generator, train_samples_num // batch_size) # 如果是32，这个除法得到的是62，抛弃了小数，故而得到1984个sample\n",
    "    np.save('E:\\PyProjects\\DataSet\\FireAI\\DeepLearning\\FireAI006/bottleneck_features_train.npy', bottleneck_features_train)\n",
    "    print('bottleneck features of train set is saved.')\n",
    "\n",
    "    generator = datagen.flow_from_directory(\n",
    "        val_data_dir,\n",
    "        target_size=(IMG_W, IMG_H),\n",
    "        batch_size=batch_size,\n",
    "        class_mode=None,\n",
    "        shuffle=False)\n",
    "    bottleneck_features_validation = model.predict_generator(\n",
    "        generator, val_samples_num // batch_size)\n",
    "    np.save('E:\\PyProjects\\DataSet\\FireAI\\DeepLearning\\FireAI006/bottleneck_features_val.npy',bottleneck_features_validation)\n",
    "    print('bottleneck features of test set is saved.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2000 images belonging to 2 classes.\n",
      "bottleneck features of train set is saved.\n",
      "Found 800 images belonging to 2 classes.\n",
      "bottleneck features of test set is saved.\n"
     ]
    }
   ],
   "source": [
    "save_bottlebeck_features()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_model():\n",
    "    '''\n",
    "    自定义一个模型，该模型仅仅相当于一个分类器，只包含有全连接层，对提取的特征进行分类即可\n",
    "    :return:\n",
    "    '''\n",
    "    # 模型的结构\n",
    "    model = Sequential()\n",
    "    model.add(Flatten(input_shape=train_data.shape[1:])) # 将所有data进行flatten\n",
    "    model.add(Dense(256, activation='relu')) # 256个全连接单元\n",
    "    model.add(Dropout(0.5)) # dropout正则\n",
    "    model.add(Dense(1, activation='sigmoid')) # 此处定义的模型只有后面的全连接层，由于是本项目特殊的，故而需要自定义\n",
    "\n",
    "    # 模型的配置\n",
    "    model.compile(optimizer='rmsprop',\n",
    "                  loss='binary_crossentropy', metrics=['accuracy']) # model的optimizer等\n",
    "\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 2000 samples, validate on 800 samples\n",
      "Epoch 1/20\n",
      "2000/2000 [==============================] - 6s 3ms/step - loss: 0.8426 - acc: 0.7455 - val_loss: 0.4280 - val_acc: 0.8063\n",
      "Epoch 2/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.3928 - acc: 0.8365 - val_loss: 0.3078 - val_acc: 0.8675\n",
      "Epoch 3/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.3144 - acc: 0.8720 - val_loss: 0.4106 - val_acc: 0.8588\n",
      "Epoch 4/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.3032 - acc: 0.8830 - val_loss: 0.3058 - val_acc: 0.8850\n",
      "Epoch 5/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.2446 - acc: 0.9050 - val_loss: 0.3050 - val_acc: 0.8962\n",
      "Epoch 6/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.2199 - acc: 0.9120 - val_loss: 0.3157 - val_acc: 0.8975\n",
      "Epoch 7/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.2057 - acc: 0.9225 - val_loss: 0.3591 - val_acc: 0.8812\n",
      "Epoch 8/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.1954 - acc: 0.9235 - val_loss: 0.4171 - val_acc: 0.8762\n",
      "Epoch 9/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.1391 - acc: 0.9475 - val_loss: 0.4773 - val_acc: 0.8738\n",
      "Epoch 10/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.1478 - acc: 0.9480 - val_loss: 0.4436 - val_acc: 0.8788\n",
      "Epoch 11/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.1105 - acc: 0.9590 - val_loss: 0.4566 - val_acc: 0.8800\n",
      "Epoch 12/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.1005 - acc: 0.9575 - val_loss: 0.4178 - val_acc: 0.8812\n",
      "Epoch 13/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0987 - acc: 0.9660 - val_loss: 0.4127 - val_acc: 0.8888\n",
      "Epoch 14/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0927 - acc: 0.9660 - val_loss: 0.4777 - val_acc: 0.8888\n",
      "Epoch 15/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0692 - acc: 0.9735 - val_loss: 0.4671 - val_acc: 0.8838\n",
      "Epoch 16/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0775 - acc: 0.9745 - val_loss: 0.5790 - val_acc: 0.8812\n",
      "Epoch 17/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0650 - acc: 0.9775 - val_loss: 0.4669 - val_acc: 0.8988\n",
      "Epoch 18/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0479 - acc: 0.9830 - val_loss: 0.5380 - val_acc: 0.9025\n",
      "Epoch 19/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0600 - acc: 0.9775 - val_loss: 0.5357 - val_acc: 0.8988\n",
      "Epoch 20/20\n",
      "2000/2000 [==============================] - 5s 3ms/step - loss: 0.0551 - acc: 0.9810 - val_loss: 0.6057 - val_acc: 0.8825\n"
     ]
    }
   ],
   "source": [
    "# 只需要训练分类器模型即可，不需要训练特征提取器\n",
    "train_data = np.load('E:\\PyProjects\\DataSet\\FireAI\\DeepLearning\\FireAI006/bottleneck_features_train.npy') # 加载训练图片集的所有图片的VGG16-notop特征\n",
    "train_labels = np.array(\n",
    "    [0] * int((train_samples_num / 2)) + [1] * int((train_samples_num / 2)))\n",
    "# label是1000个cat，1000个dog，由于此处VGG16特征提取时是按照顺序，故而[0]表示cat，1表示dog\n",
    "\n",
    "validation_data = np.load('E:\\PyProjects\\DataSet\\FireAI\\DeepLearning\\FireAI006/bottleneck_features_val.npy')\n",
    "validation_labels = np.array(\n",
    "    [0] * int((val_samples_num / 2)) + [1] * int((val_samples_num / 2)))\n",
    "\n",
    "# 构建分类器模型\n",
    "clf_model=my_model()\n",
    "history_ft = clf_model.fit(train_data, train_labels,\n",
    "              epochs=epochs,\n",
    "              batch_size=batch_size,\n",
    "              validation_data=(validation_data, validation_labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 画图，将训练时的acc和loss都绘制到图上\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "def plot_training(history):\n",
    "    plt.figure(12)\n",
    "    \n",
    "    plt.subplot(121)\n",
    "    train_acc = history.history['acc']\n",
    "    val_acc = history.history['val_acc']\n",
    "    epochs = range(len(train_acc))\n",
    "    plt.plot(epochs, train_acc, 'b',label='train_acc')\n",
    "    plt.plot(epochs, val_acc, 'r',label='test_acc')\n",
    "    plt.title('Train and Test accuracy')\n",
    "    plt.legend()\n",
    "    \n",
    "    plt.subplot(122)\n",
    "    train_loss = history.history['loss']\n",
    "    val_loss = history.history['val_loss']\n",
    "    epochs = range(len(train_loss))\n",
    "    plt.plot(epochs, train_loss, 'b',label='train_loss')\n",
    "    plt.plot(epochs, val_loss, 'r',label='test_loss')\n",
    "    plt.title('Train and Test loss')\n",
    "    plt.legend()\n",
    " \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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/fdbArqHHw68/ddfbc7g5pshLS2ysjnicE5g3z7YsyfxzUEOR6JQvrxlIB05En74AS6+GBYsgP/9z5affrL9RGDFCktAV7RodGXOT8TdSMDFCESGXbt28WIuXDrat2/PLpcvwOHHPfdA6dJw/fVQsSI0a2apJcqWhSeftAR0U6bAwoVw553RljZ/EXcjgfwYI/DPf8LSpaFts149GDMm8+1eJXDHHXectP7o0aMULFgw0+OmT5+e6TZH/qV0aXjsMXj8cWjXDq6+Gtq2tfVezj/fTEejR1tJy1tuiZ68+Qk3EnAE5P7772fdunXUq1ePRo0a0apVK7p3706dOnUA6NChAw0aNKB27dqMHz/++HHVqlXjzz//ZOPGjdSqVYtbb72V2rVr06ZNGw4cOJBpf6+88gqNGjWibt26XH/99ezfb/Vatm7dSseOHalbty5169blu+++A+Ctt97i4osvpm7duvTs2TOMZ8IRKgYOtMCxCROgW7eTFYCXkSOtctmAAZai2hEBVDWmlgYNGmhWPPecKqhu25blbnHPypUro9r/hg0btHbt2qqqOnv2bC1evLiuX7/++PYdO3aoqur+/fu1du3a+ueff6qqatWqVXX79u26YcMGLViwoP7www+qqtqlSxedMGFCpv15j1dVfeCBB/S5555TVdWuXbvqM888o6qqGRkZumvXLl2+fLnWrFlTt2/ffpIsgQh0HoHFGoPXtsPYvl21ShVbPP9iRxDk9rqOy5FAoUJmS3REjsaNG58UdPXcc89Rt25dmjZtyqZNm1gToNhs9erVqVevHgANGjRg48aNmba/fPlymjdvTp06dZg4cSIrVqwAYNasWfTv3x+AggULUqpUKWbNmkXnzp0pV64cAGeccUaofqYjBihXDj78ELZuhRtusLTxjvARd0pgyxabWCoQd5LHN6eddtrxz3PmzOHLL79k3rx5LFu2jPr16wcMyirq4+JRsGBBMrK4m3v37s0LL7zATz/9xMMPP5xlkJequhiABKdBAxg3DlJTLeDMET7i7lGaH6KFY4GSJUuyZ8+egNvS09MpU6YMxYsX5+eff2b+/Pl57m/Pnj1UqlSJI0eOMHHixOPrW7duzbhx4wCblN69ezetW7dm8uTJ7NixA4CdO3fmuX9H7NGnD9x2m2Ui/fDDaEuTuMSdEsgv0cLRpmzZsjRr1oyL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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_training(history_ft)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将本模型保存一下\n",
    "clf_model.save_weights('E:\\PyProjects\\DataSet\\FireAI\\DeepLearning\\FireAI006/top_FC_model')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
